//
//  HttpRequest.swift
//  fho
//
//  Created by 郭颢源 on 2021/3/30.
//

import UIKit
import Alamofire
import HandyJSON
import SwiftyJSON

let baseURL = ""


typealias successCallBack = (_ result: Any) -> ()
typealias failedCallBack = (_ result: Error) -> ()

class HttpRequest: NSObject {
    
    
    static let share = HttpRequest()
    /// 重写init 禁止外部初始化
    private override init(){}
    // MARK: - 网络请求管理
    fileprivate static var requestCacheArr: Array = [DataRequest]()
    
    @discardableResult
    static func request(
        _ httpType : HTTPMethod,
        _ shortURL : String,
        _ parameters : [String : Any]?,
        _ headers : HTTPHeaders,
        success : @escaping successCallBack ,
        failed :@escaping failedCallBack)
    -> DataRequest
    {
        let headers: HTTPHeaders = [
            "Content-Type": "application/json; charset=utf-8"
        ]
        //发送网络请求
        let dataRequest = AF.request(baseURL + shortURL, method: httpType, parameters: parameters, headers: headers).responseJSON { response in
            let cacheRequest = requestCacheArr.filter({ $0.request == response.request }).first
            requestCacheArr.remove(cacheRequest!)
            // 判断数据是否存在
            guard response.value != nil else {
                failed(response.error!)
                return
            }
            success(response.result)
        }
        //记录网络请求
        self.requestCacheArr.append(dataRequest)
        return dataRequest
    }
    
    @discardableResult
    static func request(
        _ method: HTTPMethod,
        _ shortURL: String,
        _ params: [String: Any]?,
        success: @escaping (_ json: JSON) -> ())
    -> DataRequest
    {
        
        let dataRequest = AF.request(baseURL + shortURL, method: method , parameters: params).responseJSON { response in
            let cacheRequest = requestCacheArr.filter({ $0.request == response.request }).first
            requestCacheArr.remove(cacheRequest!)
            
            // 判断数据是否存在
            guard let dict = response.value else { return }
            // 将数据转为字典
            let json = JSON(dict)
//            guard json["resp_code"].stringValue == "000000" else {
//                print(json["resp_message"].stringValue)
//                return
//            }
            success(json)
        }
        self.requestCacheArr.append(dataRequest)
        return dataRequest
    }
    
    // MARK: - 网络请求GET
    @discardableResult
    static func GET(
        _ shortURL: String,
        _ params: [String: Any]?,
        success: @escaping (_ json: JSON ) -> Void,
        filed: @escaping ( _ code:Int , _ msg:String ) -> Void) -> DataRequest
    {
        
        let dataRequest = AF.request(baseURL + shortURL, method: .get,  parameters: params).responseJSON { response in
            
            let cacheRequest = requestCacheArr.filter({ $0.request == response.request }).first
            requestCacheArr.remove(cacheRequest!)
            
            // 判断数据是否存在
            guard let dict = response.value else {
                print("请求失败\(String(describing: response.error))")
                filed((response.error?.responseCode)!,(String(describing: response.error)))
                return
            }
            
            // 将数据转为字典
            let json = JSON(dict)
            guard json["code"].stringValue == "1" else {
                print(json["msg"].stringValue)
                return
            }
            
            success(json)
        }
        self.requestCacheArr.append(dataRequest)
        return dataRequest
    }
    
    
    /**
     HttpRequest.GET("", nil) { (result:BaseResponse<JSTuiModel>) in
     
     }
     */
    
    /// 网络请求: GET 
    /// - Parameters:
    ///   - shortURL: URL 地址
    ///   - params: 字典参数
    ///   - success: 请求成功，回调结果。
    ///
    ///   这里需要设置泛型T对应的model : (result:BaseResponse<JSTuiModel>)
    ///   JSTuiModel 即是 Response 中的data的模型
    ///   - result: 返回结果
    @discardableResult
    static func GET<T>(
        _ shortURL: String,
        _ params: [String: Any]?,
        success: @escaping (_ result:BaseResponse<T>) -> ()) -> DataRequest
    {
        
        let dataRequest = AF.request(baseURL + shortURL, method: .get,  parameters: params).responseJSON { response in
            let cacheRequest = requestCacheArr.filter({ $0.request == response.request }).first
            requestCacheArr.remove(cacheRequest!)
            
            print("response -->\n",JSON(response.value!))
            // 判断数据是否存在
            guard let dict = response.value else {
                print("请求失败\(String(describing: response.error))")
                return
            }
            
            // 将数据转为字典
            let json = JSON(dict)
            guard json["code"].stringValue == "1" else {
                print(json["msg"].stringValue)
                return
            }
            
            // 将字典转为模型
            if let model = JSONDeserializer<BaseResponse<T>>.deserializeFrom(json: json.rawString())
            {
                success(model)
            }
            
        }
        
        self.requestCacheArr.append(dataRequest)
        return dataRequest
    }
    
    @discardableResult
    static func GET(
        _ shortURL: String,
        _ params: [String: Any]?,
        success: @escaping (_ json: JSON ) -> (Void)) -> DataRequest
    {
        
        
        let dataRequest = AF.request(baseURL + shortURL, method: .get,  parameters: params).responseJSON { response in
            let cacheRequest = requestCacheArr.filter({ $0.request == response.request }).first
            requestCacheArr.remove(cacheRequest!)
            
            // 判断数据是否存在
            guard let dict = response.value else {
                print("请求失败\(String(describing: response.error))")
                return
            }
            // 将数据转为字典
            let json = JSON(dict)
            guard json["code"].stringValue == "1" else {
                print(json["msg"].stringValue)
                return
            }
            
            success(json)
        }
        
        self.requestCacheArr.append(dataRequest)
        return dataRequest
    }
    // MARK: - 网络请求POST
    
    @discardableResult
    static func POST(
        _ shortURL: String,
        _ params: [String: Any]?,
        success: @escaping (_ json: JSON ) -> (Void)) -> DataRequest
    {
        
        let dataRequest = AF.request(baseURL + shortURL, method: .post,  parameters: params).responseJSON { response in
            let cacheRequest = requestCacheArr.filter({ $0.request == response.request }).first
            requestCacheArr.remove(cacheRequest!)
            // 判断数据是否存在
            guard let dict = response.value else {
                print("POST请求失败\(String(describing: response.error))")
                return
            }
            
            // 将数据转为字典
            let json = JSON(dict)
            guard json["code"].stringValue == "1" else {
                print(json["msg"].stringValue)
                return
            }
            success(json)
        }
        self.requestCacheArr.append(dataRequest)
        return dataRequest
    }
    
    
    /// 网络请求POST
    /// - Parameters:
    ///   - shortURL: url 地址
    ///   - params: 参数：字典
    ///   - success: 请求回调
    ///   - result: 返回数据模型 - BaseResponse<T>: 传入数据模型
    
    @discardableResult
    static func POST<T>(
        _ shortURL: String,
        _ params: [String: Any]?,
        success: @escaping (_ result: BaseResponse<T> ) -> (Void)) -> DataRequest
    {
        
        let dataRequest = AF.request(baseURL + shortURL, method: .post,  parameters: params).responseJSON { response in
            let cacheRequest = requestCacheArr.filter({ $0.request == response.request }).first
            requestCacheArr.remove(cacheRequest!)
            // 判断数据是否存在
            guard let dict = response.value else {
                print("POST请求失败\(String(describing: response.error))")
                return
            }
            
            // 将数据转为字典
            let json = JSON(dict)
            guard json["code"].stringValue == "1" else {
                print(json["msg"].stringValue)
                return
            }
            
            // 将字典转为模型
            if let model = JSONDeserializer<BaseResponse<T>>.deserializeFrom(json: json.rawString())
            {
                success(model)
            }
        }
        self.requestCacheArr.append(dataRequest)
        return dataRequest
    }
    // MARK: - 移除网络请求
    static func cancleAllRequest()  {
        for task in requestCacheArr{
            
            task.cancel()
        }
        requestCacheArr.removeAll()
    }
}


/// 服务端返回的数据模型
class BaseResponse<T: HandyJSON>: HandyJSON {
    var code: Int?  // 服务端返回状态码
    var msg: String?    //服务端返回提示信息
    var data: T?    // 具体的data的格式和业务相关，故用泛型定义

    public required init() {}
}



///使用示例
/*
 
 // 假设这是某一个业务具体的数据格式定义
 struct SampleData: HandyJSON {
     var id: Int?
 }

 let sample = SampleData(id: 2)
 let resp = BaseResponse<SampleData>()
 resp.code = 200
 resp.data = sample

 let jsonString = resp.toJSONString()! // 从对象实例转换到JSON字符串
 print(jsonString) // print: {"code":200,"data":{"id":2}}

 if let mappedObject = JSONDeserializer<BaseResponse<SampleData>>.deserializeFrom(json: jsonString) { // 从字符串转换为对象实例
     print(mappedObject.data?.id)
 }

 */
